package grisar.gris;

import grisar.gris.helpers.DataHolder;
import grisar.gris.helpers.ResourceAllocator;
import grisar.gris.logic.Spawner;
import grisar.gris.struct.I_Ballistic;
import grisar.gris.struct.I_Drawable;
import grisar.gris.struct.I_Tower;
import grisar.gris.struct.MPoint;
import grisar.gris.struct.ballistics.TargetingMissile;
import grisar.gris.struct.enemy.Enemy;
import grisar.gris.struct.enemy.I_Enemy;
import grisar.gris.struct.ground.Ground;
import grisar.gris.struct.ground.I_Ground;
import grisar.gris.tower.I_TowerFactory;
import grisar.gris.tower.SampleTower;
import grisar.gris.tower.Tower1Factory;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;

public class KennyOMFGTDView extends View {
	
	
	boolean running 					= true;
	long lastFrameTime 					= System.currentTimeMillis();
	private Paint backgroundColor 		= new Paint();
	private Paint testColor 			= new Paint();
	int prevX, prevY, clickedX, clickedY;
	List<I_Tower> towers 				= new ArrayList<I_Tower>();
	List<I_Ground> ground 				= new ArrayList<I_Ground>();
	List<I_Enemy> enemies 				= new ArrayList<I_Enemy>();;
	List<Spawner> spawners 				= new ArrayList<Spawner>();
	Bitmap testBitmap 					= null;
	Bitmap testBitmap2;
	Bitmap roadStraightBitmap, roadTurnBitmap, roadIntersectionBitmap, roadTCrossBitmap;
	I_TowerFactory towerFactory;
	I_Tower activeTower;

	TargetingMissile krisBallistic;
	
	Set<Point> roadTilePoints;
	MapParser mapParser;
	
	private int tileSizeX = 64, tileSizeY = 64;
	
	
	private RefreshHandler redrawHandler = new RefreshHandler();
	class RefreshHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			KennyOMFGTDView.this.update();
			KennyOMFGTDView.this.invalidate();
		}

		public void sleep(long delayMillis) {
			if (running) {
				this.removeMessages(0);
				sendMessageDelayed(obtainMessage(0), delayMillis);

				lastFrameTime = System.currentTimeMillis();
			}
		}	
	}
	public KennyOMFGTDView(Context context) {
		super(context);
		
		ResourceAllocator.registerContext(context);
		
		// Load first level:
		mapParser = new MapParser(0);
		
		// Initiliaze store of data		
		DataHolder.loadMap(mapParser, enemies, null, towers, ground, spawners);
		
		//TestOo mapparser = new TestOo("");
		
		backgroundColor.setColor(Color.BLACK);
		testColor.setColor(Color.WHITE);
		
		krisBallistic = new TargetingMissile( 2, null );
		
		// Get all coordinates for the roadtiles
		roadTilePoints = mapParser.getRoadPoints();
		

		testBitmap = resize(((BitmapDrawable)(context.getResources().getDrawable(R.drawable.green))).getBitmap(), 64, 64);
		testBitmap2 = resize(((BitmapDrawable)(context.getResources().getDrawable(R.drawable.tower2a))).getBitmap(), 64, 64);
		
		roadStraightBitmap =  resize(((BitmapDrawable)(context.getResources().getDrawable(R.drawable.road))).getBitmap(), 64, 64);
		
		
		
		spawnGround(context);
		towers.add(new SampleTower(new Point(100,100),testBitmap));
		towers.add(new SampleTower(new Point(300,300),testBitmap2));
		activeTower = new SampleTower(new Point(300,300),testBitmap2);
		towerFactory = new Tower1Factory(testBitmap);
		Spawner spawner = new Spawner();
		spawner.loadScript(Spawner.scriptEnemy(1, 2, 5, 1, 2)+
						   Spawner.scriptEnemy(2, 2, 5, 1, 2)+
						   Spawner.scriptEvent(1, 0, 2000, 100)+
						   Spawner.scriptEvent(2, 6000, 10000, 200));
		spawner.setPosition(new Point(100,100));
		spawners.add(spawner);
		
		new Thread() {
			public void run() {
				//long time method
				while(true){
					redrawHandler.sleep(300);
					redrawHandler.sendEmptyMessage(0);
				}
			}
		}.start();
	}
	public void update() {
		
		krisBallistic.update();
		
		for(Spawner s : spawners){
			s.update();
		}
		
		for(I_Enemy e : enemies){
			e.update();
		}
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		I_Tower tower = towerFactory.getTower();
		tower.setPosition(new Point(clickedX,clickedY));
		
		boolean collide = false;
		for(I_Tower t : towers){
			if(t.isColliding(tower)){
				collide=true;
				break;
			}
		}
		
		Enemy enemy = new Enemy(ResourceAllocator.getDrawable(R.drawable.tower2a, true)); 
		enemy.setPosition(new Point(clickedX,clickedY));
		enemies.add(enemy);
		
		prevX = clickedX;
		prevY = clickedY;
		clickedX = (int) event.getX();
		clickedY = (int) event.getY();
		this.invalidate();
		return true;
	} 
	
	//TODO remove
	//Sampel gras maker
	public void spawnGround(Context context){
		
		Bitmap groundBitmap  = resize(((BitmapDrawable)(context.getResources().getDrawable(R.drawable.green))).getBitmap(), 64, 64);
		
		for (int y=0; y < 8; y++){
			for (int x=0; x < 13; x++){
				ground.add(new Ground(new Point(x*64,y*64), groundBitmap));
			}
		}
	}
	
	@Override
	public void onDraw(Canvas canvas) {
		// Bakgrund måla inget annat innan denna:
		canvas.drawRect(0, 0, getWidth(), getHeight(), backgroundColor);

		
			for(I_Drawable g : ground){
			g.draw(canvas);
		}		
		// Draw the road
		for (Point p : roadTilePoints) {
			if (mapParser.getRoadBitmaps().get(p) != null)
				canvas.drawBitmap(mapParser.getRoadBitmaps().get(p), p.x*tileSizeX, p.y*tileSizeY, null);
		}
		
		for(I_Enemy e : enemies){
			e.draw(canvas);
		}
		
		for(I_Drawable d : towers){
			d.draw(canvas);
		}

		canvas.drawLine(prevX, prevY, clickedX, clickedY, testColor);
		
		if(activeTower!=null){
			activeTower.setPosition(new Point(clickedX,clickedY));
			activeTower.draw(canvas);
		}

		
		krisBallistic.draw(canvas);	}
	
	
	


	/**
	 * Resizes a bitmap
	 * @param orgBitmap the bitmap to be resized
	 * @param x width of the new bitmap 
	 * @param y height of the new bitmap
	 * @return returns the new bitmap
	 */
	public Bitmap resize(Bitmap orgBitmap, int x, int y) {
		if (orgBitmap.getWidth() == x && orgBitmap.getHeight() == y)
			return orgBitmap;

		return Bitmap.createScaledBitmap(orgBitmap, x, y, false);
	}
	/**
	 * Rotates a bitmap
	 * @param degrees degrees to rotate the bitmap
	 * @param orgBitmap The bitmap to rotate
	 * @return returns the new rotated bitmap
	 */
	public Bitmap rotate(int degrees, Bitmap orgBitmap) {
		Matrix matrix = new Matrix();
		matrix.postRotate(degrees);
		if (degrees == 90 || degrees == 270) {
			orgBitmap = Bitmap.createScaledBitmap(orgBitmap, orgBitmap.getHeight(), orgBitmap.getWidth(), false);
			Bitmap rotatedBitmap = Bitmap.createBitmap(orgBitmap, 0, 0, orgBitmap.getWidth(), orgBitmap.getHeight(), matrix, true);
			return rotatedBitmap;
		}
		else {
			Bitmap rotatedBitmap = Bitmap.createBitmap(orgBitmap, 0, 0, orgBitmap.getWidth(), orgBitmap.getHeight(), matrix, true);
			return rotatedBitmap;	
		}
	}
	
	public MapParser getMP() {
		return mapParser;
	}


}
